Using View Devices
This section demonstrates how to use QuickDraw GX view devices. It shows how you can
- create and manipulate view device objects and their properties
- get and set a view device's clip and mapping
- identify the view devices of a shape
- measure a shape in the device space of a view device
- hit-test a shape on a device
Creating and Manipulating View Device Objects
Normally, your application needs to create view device objects only for offscreen drawing. QuickDraw GX creates view device objects for all attached screen devices at startup. If you do need to create a view device object, QuickDraw GX provides theGXNewViewDevice
function, to which you must supply a view group reference and a bitmap shape representing the device's imaging area and characteristics. You can also create a new view device object by copying an existing one, using theGXCopyToViewDevice
function.Once you have created a view device object, you can customize its features using the techniques described in the following sections.
You can test if two view device-object references refer to the same view device object by simply testing the references for equality. You can also test a view device for equality with another view device with the
GXEqualViewDevice
function. For two view device objects to be equal, their clips, mappings, bitmap shapes, and attributes must be identical, and they must be in the same view group, represent the same Macintosh graphics device (sameGDevice
record), and point to the same pixel image, color set, and color profile. Their tag lists need not be identical. View device object copies created with theGXCopyToViewDevice
function are always equal to the view device from which they were copied.To delete your application's reference to a view device object, call the
GXDisposeViewDevice
function. Because view device objects have no owner count, callingGXDisposeViewDevice
actually releases the memory allocated for that view device object, and invalidates all other references to it.Listing 7-9 is a portion of a printer driver routine that sets up a default printing
view device. It first sets up a bitmap structure with default values, and then creates
a bitmap shape to pass toGXNewViewDevice
. The view group for this view device
isgxScreenViewDevices
, because it is to be used for printing, not offscreen
drawing.Listing 7-9 Creating a new view device
gxBitmap aBitmap; gxViewDevice vd; aBitmap.pixelSize = 1; aBitmap.rowBytes = 0; aBitmap.width = 0; aBitmap.height = 0; aBitmap.image = nil; aBitmap.space = gxNoSpace; aBitmap.set = nil; aBitmap.profile = nil; theBitmap = GXNewBitmap(&aBitmap, nil); ./* error-check here (not shown) */ . . vd = GXNewViewDevice(gxScreenViewDevices, theBitmap); ./* error-check here (not shown) */ . .When the driver is finished with the view device, it disposes of it with this line:
GXDisposeViewDevice(vd);Listing 7-10 demonstrates creating a new view device by using theGXCopyToViewDevice
function. Like Listing 7-2 on page 7-44, it is part of a
routine that creates an offscreen view group (newGroup
) that is a copy of an
existing view group (group
). For each view device in the onscreen view group,
the routine creates a copy and assigns it to the offscreen view group.The routine decrements the
count
variable to control incrementing through the list
of view devices (list
) belonging to the onscreen view group.Listing 7-10 Copying the view devices from one view group to another
long deviceCount = GXGetViewGroupViewDevices(group,nil); long count = deviceCount; gxViewDevice *deviceList = (void *)NewPtr(deviceCount * sizeof(gxViewDevice)); gxViewDevice *list = deviceList; GXGetViewGroupViewDevices(group, deviceList); while (count-- > 0) { GXSetViewDeviceViewGroup(*list = GXCopyToViewDevice(nil, *list), newGroup); list++; }TheGXNewViewDevice
function is described on page 7-98. TheGXDisposeViewDevice
function is described on page 7-99.
TheGXCopyToViewDevice
function is described on page 7-100. TheGXEqualViewDevice
function is described on page 7-101.Manipulating View Device Object Properties
This section describes how to manipulate the bitmap, view group, and attributes properties of a view device object:
How to manipulate other view device properties is described in subsequent sections, starting with "Getting and Setting a View Device's Clip and Mapping" on page 7-56.
- To manipulate the bitmap structure, you use the functions
GXGetViewDeviceBitmap
andGXSetViewDeviceBitmap
.- To manipulate the view group reference, you use the functions
GXGetViewDeviceViewGroup
andGXSetViewDeviceViewGroup
.- To manipulate the view device attributes, you use the functions
GXGetViewDeviceAttributes
andGXSetViewDeviceAttributes
.- To manipulate the view device tag list, you use the functions
GXGetViewDeviceTags
andGXSetViewDeviceTags
.
Getting and Setting a View Device's Bitmap
The following code fragment is a function that usesGXGetViewDeviceBitmap
to gain access to a copy of the color set of a view device, clone its reference (so it won't be deleted when its bitmap is disposed of), and then return it as a function result. The function needs the bitmap shape itself only temporarily, and therefore disposes of it after extracting the color set reference from it.
gxColorSet GetViewDeviceColorSet(gxViewDevice source) { register gxShape bitmapShape = GXGetViewDeviceBitmap(source); register gxColorSet result = GetShapeColorSet(bitmapShape); if (result) GXCloneColorSet(result); GXDisposeShape(bitmapShape); return result; }The following code fragment is a function that usesGXSetViewDeviceBitmap
to assign a color profile to a view device. The function disposes of its reference to the bitmap shape after assigning it to the view device.
void SetViewDeviceColorProfile(gxViewDevice target, gxColorProfile profile) { register gxShape bitmapShape = GXGetViewDeviceBitmap(target); SetShapeColorProfile(bitmapShape, profile); GXSetViewDeviceBitmap(target, bitmapShape); GXDisposeShape(bitmapShape); }TheGXGetViewDeviceBitmap
function is described on page 7-107; theGXSetViewDeviceBitmap
function is described on page 7-108.Getting and Setting a View Device's View Group
You can use theGXGetViewDeviceViewGroup
function to retrieve the view group that a view device belongs to, and you can use theGXSetViewDeviceViewGroup
to change the view group of a view device. Listing 7-10 on page 7-54 shows an example of usingGXSetViewDeviceViewGroup
to reassign the copy of a view device from one view group to another.The
GXGetViewDeviceViewGroup
function is described on page 7-109; theGXSetViewDeviceViewGroup
function is described on page 7-109.Getting and Setting a View Device's Attributes and Tag References
You can examine the attributes of a view device object using theGXGetViewDeviceAttributes
function. You can set the attributes of a view device object using theGXSetViewDeviceAttributes
function. By setting attributes, you can influence whether the device bitmap is placed on an accelerator card and whether the device is active or inactive.You can examine the list of references to tag objects currently associated with a view device object using the
GXGetViewDeviceTags
function. Once you create a tag
object, you can attach it to a view device object using theGXSetViewDeviceTags
function. You can attach as many tag objects as you like to a view device object.Tag objects and the basic functions for manipulating them are described in the chapter "Tag Objects" in this book. That chapter also lists the common tag types defined and reserved by Apple Computer, Inc.
The
GXGetViewDeviceAttributes
function is described on page 7-110; theGXSetViewDeviceAttributes
function is described on page 7-111. View device attributes are described in the section "View Device Attributes" on page 7-27.The
GXGetViewDeviceTags
function is described on page 7-112. TheGXSetViewDeviceTags
function is described on page 7-113.Getting and Setting a View Device's Clip and Mapping
The clip and mapping properties of a view device control its active imaging area, its scale (pixel size), and its position in global space. For onscreen view devices and printing view devices, you cannot change the clip or mapping properties; they are set by QuickDraw GX. For offscreen view devices, you can set the clip and mapping yourself. The functions you use areGXGetViewDeviceClip
,GXSetViewDeviceClip
,GXGetViewDeviceMapping
, andGXSetViewDeviceMapping
.Listing 7-11 is a utility routine that returns a mapping matrix that converts from local space (or from the identity mapping, if the view port is
nil
) to device space (or to
global space, if the view device isnil
). It usesGXGetViewDeviceMapping
to retrieve the view device's mapping matrix. (If the view device isnil
, the routine uses the mapping matrix returned by theGXGetViewPortGlobalMapping
function.) The routine also makes use of theMapMapping
function, described in the mathematics chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.Listing 7-11 Returning the mapping from local to device space
static void GetSpaceMapping(gxViewPort port, gxViewDevice device, gxMapping *map) { if (port) GXGetViewPortGlobalMapping(port, map); else ResetMapping(map); if(device) { gxMapping temp; MapMapping(map, GXGetViewDeviceMapping(device, &temp)); } }The following code fragment is part of a printer driver routine that sets up a default view device. This section of code rescales the mapping matrix (vdMapping
) of the view device (vd
) from the default resolution (72 ppi, as specified by the identity matrix) to the horizontal and vertical resolution of the printer (kHorizHighRes
andkVertHighRes
). To do the scaling, the code uses theScaleMapping
function, described in the mathematics chapter of Inside Macintosh: QuickDraw GX Environment and Utilities. It then uses GXSetViewDeviceMapping to assign the scaled mapping to the view device.
Fixed xScale; Fixed yScale; xScale = FixRatio(kHorizHighRes, 72); yScale = FixRatio(kVertHighRes, 72); ResetMapping(&vdMapping); ScaleMapping(&vdMapping, xScale, yScale, ff(0), ff(0)); GXSetViewDeviceMapping(vd, &vdMapping);TheGXGetViewDeviceClip
function is described on page 7-102; theGXSetViewDeviceClip
function is described on page 7-103.The
GXGetViewDeviceMapping
function is described on page 7-105; theGXSetViewDeviceMapping
function is described on page 7-106.Identifying a Shape's View Devices
TheGXGetShapeGlobalViewDevices
function returns a list of all view devices that a shape would actually appear in if it were drawn. The function can test the shape against all the shape's view ports, or you can specify a single view port for the test.You can use
GXGetShapeGlobalViewDevices
to avoid the overhead of testing the drawing characteristics (such as the colors) of shapes on devices that they cannot be drawn to.Listing 7-12 is part of a library routine that sets up a data structure for offscreen drawing through a given view port. This part of the code creates a full shape--which covers all of coordinate space--and passes it to
GXGetShapeGlobalViewDevices
to derive a count of all view devices that could be drawn on through the given port. (Note that, for the purpose of retrieving all the view devices of a view port, you could also use theGXGetViewPortViewDevices
function.)Listing 7-12 Setting up a data structure for offscreen drawing
viewPortBuffer NewViewPortBuffer(gxViewPort port) { viewPortBuffer buffersHandle; viewPortBufferRecord *buffers; gxTransform xform; gxShape area; long deviceCount; short i; NilParamReturnNil(port); /* error check port parameter */ area = GXNewShape(gxFullType); xform = GXNewTransform(); GXSetTransformViewPorts(xform, 1, &port); GXSetShapeTransform(area, xform); GXDisposeTransform(xform); deviceCount = GXGetShapeGlobalViewDevices(area, port, nil); . . /* continued as Listing 7-13 on page 7-61 */ .TheGXGetShapeGlobalViewDevices
function is described on page 7-115.Measuring a Shape in Device Space
You can use view device functions to measure a shape on a device in three ways:
The
- The
GXGetShapeDeviceBounds
function measures the position and size of the bounding rectangle of a shape on a device, in device coordinates.- The
GXGetShapeDeviceArea
function determines the area of a shape (in pixels) on a device.- The
GXGetShapeDeviceColors
function determines the colors with which a shape would be drawn on a device.
GXGetShapeDeviceBounds
function determines whether any part of a shape intersects a view device, and if so, returns the bounding rectangle of that part of the shape in device coordinates. You can thus useGXGetShapeDeviceBounds
to measure the size of a shape on a view device and to compare it with other shapes on the device. (To measure a shape in the local space of a view port, you can use theGXGetShapeLocalBounds
function; to measure a shape in the global space of a view group, useGXGetShapeGlobalBounds
.)The following is a fragment of a function that converts a QuickDraw GX shape on a device into a QuickDraw picture. It uses
GXGetShapeDeviceBounds
to get the shape's bounding rectangle on the device, converts that rectangle into a QuickDrawrect
structure, further converts it to QuickDraw local coordinates, and uses that to define the picture bounding rectangle. After that, the function converts the shape itself (not shown).
GXGetShapeDeviceBounds(theShape, 0, 0, &shapeBounds); picRect.left = FixedToInt(shapeBounds.left); picRect.top = FixedToInt(shapeBounds.top); picRect.right = FixedToInt(shapeBounds.right); picRect.bottom = FixedToInt(shapeBounds.bottom); GlobalToLocal((Point*) &picRect.top); GlobalToLocal((Point*) &picRect.bottom); thePicture = OpenPicture(&picRect); . . /* convert the shape (not shown) */ .The QuickDraw functionsGlobalToLocal
andOpenPicture
, and the data typesPoint
andRect
are described in Inside Macintosh: Imaging With QuickDraw.
The
- Note
- You do not need to write special functions to convert
QuickDraw pictures into QuickDraw GX shapes. You can use
the QuickDraw-to-QuickDraw GX translator for that; see the
Macintosh environment chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.![]()
GXGetShapeDeviceBounds
function is described on page 7-116. TheGXGetShapeDeviceArea
function is described on page 7-118.
TheGXGetShapeDeviceColors
function is described on page 7-119.
GXGetShapeGlobalBounds
function is described on page 7-125.
TheGXGetShapeLocalBounds
function, described on page 7-96.Hit-Testing a Shape on a Device
TheGXHitTestDevice
function is one of several hit-testing functions provided
by QuickDraw GX. Hit-testing in general is described in the chapter "Introduction to QuickDraw GX" in this book; shape parts for hit-testing are described in the chapter "Transform Objects" in this book.You use
GXHitTestDevice
instead ofGXHitTestShape
orGXHitTestPicture
--or before them--when it is important to take into account whether a shape is actually visible on a device. UnlikeGXHitTestShape
andGXHitTestPicture
,GXHitTestDevice
accounts for clipping and does not return successful hits for shapes that are not actually drawn.Another significant difference is that the tolerance for
GXHitTestDevice
defines a rectangular area of pixels, not the circular geometry area used byGXHitTestShape
andGXHitTestPicture
. Thus you can use the tolerance value forGXHitTestDevice
as something like a clip area, expanding it to cover an entire window or contracting it to one or a few complete pixels.What
GXHitTestDevice
does not do thatGXHitTestShape
andGXHitTestPicture
do is analyze the parts of a shape. If you are hit-testing in order to highlight specific parts of a shape, for example, you can first callGXHitTestDevice
to determine which shape was actually hit, and then callGXHitTestShape
orGXHitTestPicture
to determine the part or parts to highlight.The
GXHitTestDevice
function is described on page 7-120. TheGXHitTestShape
function is described in the chapter "Shape Objects" in this book. TheGXHitTestPicture
function is described in the picture shapes chapter of Inside Macintosh: QuickDraw GX Graphics.